import httpx
from fastmcp import FastMCP
from urllib.parse import quote

# 初始化MCP服务器
mcp = FastMCP("WeatherService")


async def get_weather_data(city_name: str) -> dict:
    """
    获取指定城市的天气信息（支持中文城市名）
    :param city_name:
    :return:
    """
    try:
        # 对中文城市名进行URL编码
        encoded_city = quote(city_name)

        # 后续可以换成其它天气服务
        url = f"https://wttr.in/{encoded_city}?format=j1&lang=zh"
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
            "Accept-Language": "zh-CN,zh;q=0.9"  # 确保返回中文结果
        }

        # 使用httpx异步获取数据
        async with httpx.AsyncClient(timeout=30.0, follow_redirects=True) as client:
            response = await client.get(url, headers=headers)
            response.raise_for_status()  # 检查HTTP错误

            # 检查响应内容是否为JSON
            content_type = response.headers.get('Content-Type', '')
            if 'application/json' not in content_type:
                # 尝试处理可能的HTML错误响应
                if '<!DOCTYPE html>' in response.text:
                    return {"error": "服务返回了HTML页面，可能是城市名称无效"}
                return {"error": f"意外的响应类型: {content_type}"}

            data = response.json()

            # 解析当前天气数据
            current = data["current_condition"][0]
            weather = data["weather"][0]

            # 提取所需信息
            return {
                "city": city_name,
                "current_weather": current["lang_zh"][0]["value"],  # 中文天气描述
                "current_temp": current["temp_C"],
                "temp_min": weather['mintempC'],
                "temp_max": weather['maxtempC'],
                "wind_speed": current["windspeedKmph"],
                "humidity": current["humidity"]
            }
    except httpx.HTTPStatusError as e:
        return {"error": f"HTTP错误: {e.response.status_code}"}
    except httpx.RequestError as e:
        return {"error": f"网络请求失败: {str(e)}"}
    except (KeyError, IndexError) as e:
        return {"error": f"数据解析失败: {str(e)}"}
    except Exception as e:
        return {"error": f"未知错误: {str(e)}"}


def format_weather(data: dict, city_name) -> str:
    """
    格式化天气信息
    :param data:
    :param city_name:
    :return:
    """
    current_weather = data["current_weather"]
    current_temp = data["current_temp"]
    temp_min = data['temp_min']
    temp_max = data['temp_max']
    humidity = data["humidity"]
    wind_speed = data["wind_speed"]

    return (
        f"🌍 城市: {city_name}\n"
        f"🌤 当前天气: {current_weather}\n"
        f"🌡 当前温度: {current_temp}°C\n"
        f"📈 今日温度范围: {temp_min}°C ~ {temp_max}°C\n"
        f"💧 湿度: {humidity}%\n"
        f"🌬 风速: {wind_speed} m/s\n"
    )


@mcp.tool(name="query_weather", description="查询指定城市的天气信息")
async def query_weather(city_name: str) -> str:
    """
    输入城市名称，返回该城市的当前天气信息

    参数:
        city_name (str): 城市名称（如"北京"）

    返回:
        str: 格式化后的天气信息
    """
    try:
        # 获取天气数据
        weather_data = await get_weather_data(city_name)

        # 格式化结果
        return format_weather(weather_data, city_name)
    except Exception as e:
        return f"❌ 发生异常: {str(e)}"


if __name__ == "__main__":
    # 以SSE模式运行MCP服务，端口8090
    mcp.run(
        transport="sse",
        host="0.0.0.0",
        port=8090,
        log_level="info"
    )
